module uart_tb();

event		lsy;
event		haha;
reg			  clk;
reg			  rst;
reg			  cs;
reg			  wr;
reg			  rd;
reg		[7:0] read_addr;
reg		[7:0] write_addr;
reg		[7:0] data_in;

wire	[7:0] data_out;
wire		  int_o;

wire		  srx_i;
wire		  stx_o;
integer 		 i;

uart_top uUART(
	.clk			(clk		), 
	.rst			(rst		),
	.cs				(cs			),
	.wr				(wr			),
	.rd				(rd			),
	.read_addr		(read_addr	),
	.write_addr		(write_addr	),
	.data_in		(data_in	),
	.data_out		(data_out	),
	.int_o			(int_o		),
                                
	.stx_o			(stx_o		),
	.srx_i			(srx_i		)
);

assign	srx_i = stx_o;

initial clk=0;
always #5 clk=~clk;

initial		
begin
	cs = 0;
	wr = 0;
	rd = 0;
	rst = 0;
	read_addr = 0;
	write_addr = 0;
	data_in = 0;
	
	#5;
	rst = 1;
	#10;
	rst = 0;

	write_register(8'h3,8'b10000000);	//set LCR.7 = 1  for access PRER
	write_register(8'h1,8'h00);			//prer_high byte
	write_register(8'h0,8'h01);			//prer_low	byte
	write_register(8'h3,8'b00011011);	//write LCR prity even and 1 stop bits and 8 bits
	write_register(8'h2,8'b00000000);	//FCR, choose rx fifo trigger level
	write_register(8'h5,8'd250);			//set rx fifo trigger level
	write_register(8'h2,8'b10000000);   //FCR, choose tx fifo trigger level
	write_register(8'h5,8'h6);			//set tx fifo trigger level
	write_register(8'h1,8'b00000111);	//enable all interrupts
	#1000;
	write_register(8'h0,8'h01);
	write_register(8'h0,8'h12);
	#3000;
	//read_register (8'h2);	//read iir
	#3000;
	write_register(8'h0,8'h12);
	write_register(8'h0,8'h23);
	write_register(8'h0,8'h34);
	write_register(8'h0,8'h45);
	write_register(8'h0,8'h56);
	write_register(8'h0,8'h67);
	write_register(8'h0,8'h78);
	write_register(8'h0,8'h89);
	write_register(8'h0,8'h9A);
	write_register(8'h0,8'hAB);
	write_register(8'h0,8'hBC);
	write_register(8'h0,8'hCD);
	write_register(8'h0,8'hDE);
	write_register(8'h0,8'hEF);

	#200000;
	write_register(8'h2,8'b00000100);
	for(i=0;i<256;i=i+1)
	begin
		->lsy;
		write_register(8'h0,i);
		->haha;
	end
	for(i=255;i>=0;i=i-1)
	begin
		->lsy;
		write_register(8'h0,i);
		->haha;
	end
	#20000;

	while (~int_o)
	begin
	#1;
	end

	read_register(8'h1);
	read_register(8'h0);
	read_register(8'h0);
	read_register(8'h0);
	read_register(8'h0);
	read_register(8'h0);
	read_register(8'h0);
	read_register(8'h0);
	read_register(8'h0);
	read_register(8'h0);
	read_register(8'h0);
	read_register(8'h0);
	read_register(8'h0);
	read_register(8'h0);
	read_register(8'h0);

 	#800000;
	$stop;
end




task write_register;
	input	[7:0] addr;
	input	[7:0] data;
begin
	@ (posedge clk )
	#1;
	cs = 1;
	wr = 1;
	write_addr = addr;
	data_in = data;
	@ (posedge clk)
	#1
	cs = 0;
	wr = 0;
	write_addr = 8'h0;
	data_in = 8'h0;
end
endtask

task read_register;
	input	[7:0] addr;
begin
	@ (posedge clk)
	#1;
	cs = 1;
	rd = 1;
	read_addr = addr;
	@ (posedge clk)
	#1;
	cs = 0;
	rd = 0;
	read_addr = 0;
end
endtask

endmodule
